package enemy
{
	import org.flixel.*;
	import org.flixel.plugin.photonstorm.*;
	import flash.utils.*;
	
	import enemy.*;
	import item.*;
	
	/**
	 * ...
	 * @author JAC
	 */
	public class Runner extends Unit
	{
		private static const WONDERING:uint = 0;
		private static const RUNNING:uint = 1;
		private static const TIRED:uint = 2;
		private static const DYING:uint = 3;
		
		private var timer:FlxDelay;
		private var state:uint;
		private var drops:Dictionary;
		
		public function Runner(i:int = 0, j:int = 0)
		{
			super(i, j);

			loadGraphic(Asset.ImgRunner, true);
			
			addAnimation("default", [1, 0, 1, 2], 6);
			play("default");
			
			timer = new FlxDelay(0);
			state = WONDERING;
			
			drops = new Dictionary();
			drops[getQualifiedClassName(enemy.EvilSpirit)] = 0.9;
		}
		
		override public function update():void
		{
			changeAnimation();
			
			if (state == WONDERING)
			{
				if (sawPlayer(3))
				{
					state = RUNNING;
					goToRandomTile(150, true);
					say("GHOST!!!", 110, 2);
					return;
				}
				
				if (needNewPath())
				{
					goToRandomTile();
				}
			}
			else if (state == RUNNING)
			{
				if (needNewPath())
				{
					state = TIRED;
					velocity.make(0, 0);
					timer.reset(3000);
					say("That was close!", 110, 3);
					return;
				}
			}
			else if (state == TIRED)
			{
				if (timer.hasExpired)
				{
					state = WONDERING;
					return;
				}
			}
			else if (state == DYING)
			{
				if (timer.hasExpired)
				{
					spawnDrops();
					super.kill();
					destroy();
					FlxG.state.remove(this);
				}
			}
		}
		
		override public function kill():void
		{
			state = DYING;
			stopFollowingPath();
			velocity.make(0, 0);
			visible = false;
			solid = false;
			timer.reset(3000);
			say("NO! THIS CANNOT BE!", 110, 3);
		}
		
		override public function destroy():void
		{
			timer = null;
			drops = null;
			
			super.destroy();
		}
		
		protected function goTo(destination:FlxPoint, speed:Number = 100, avoidPlayer:Boolean = false):Boolean
		{
			var path:FlxPath;
			if (avoidPlayer)
			{
				path = Registry.maze.findPathAvoidingPlayer(getMidpoint(), destination);
			}
			else
			{
				path = Registry.maze.findPath(getMidpoint(), destination);
			}
			
			if (path == null)
			{
				return false;
			}
			else
			{
				followPath(path, speed);
				return true;
			}
		}
		
		protected function needNewPath():Boolean
		{
			return pathSpeed == 0;
		}
		
		protected function goToRandomTile(speed:Number = 100, avoidPlayer:Boolean = false):void
		{
			goTo(Registry.maze.getRandomPathTileCenter(), speed, avoidPlayer);
		}
		
		protected function sawPlayer(viewDistance:uint, useSight:Boolean = true):Boolean
		{
			if (useSight)
			{
				return Registry.maze.playerIsInSight(getMidpoint(), facing, viewDistance) > 0;
			}
			else
			{
				return Registry.maze.playerIsInSight(getMidpoint(), FlxObject.NONE, viewDistance) > 0;
			}
		}
		
		protected function changeAnimation():void
		{
			if (velocity.y < 0)
			{
				facing = UP;
			}
			else if (velocity.y > 0)
			{
				facing = DOWN;
			}
			else if (velocity.x < 0)
			{
				facing = LEFT;
			}
			else if (velocity.x > 0)
			{
				facing = RIGHT;
			}
		}
		
		protected function spawnDrops():void
		{
			for (var key:String in drops)
			{
				var unit:Class = getDefinitionByName(key) as Class;
				var chance:Number = drops[key];
				if (FlxG.random() < chance)
				{
					var tileIndex:FlxPoint = Registry.maze.getTileByPoint(getMidpoint());
					FlxG.state.add(new unit(tileIndex.x, tileIndex.y));
				}
			}
		}
	}
}